const { createApp, ref, reactive, onMounted, nextTick } = Vue;
const { PDFDocument, rgb, StandardFonts } = PDFLib;

createApp({
    setup() {
        const pdfFile = ref(null);
        const pdfDoc = ref(null);
        const pdfLoaded = ref(false);
        const editorActive = ref(false); // New state for editor activation
        const numPages = ref(0);
        const currentPage = ref(1);
        const zoomLevel = ref(1.0);
        const zoomLevelInput = ref(100);
        const displayMode = ref('single'); // 'single', 'double', 'cover'
        const uploadError = ref(null);
        const directEditMode = ref(false); // To track if user wants to go directly to edit mode
        console.log('Initial state: pdfLoaded:', pdfLoaded.value, 'editorActive:', editorActive.value);

        const annotationHistory = reactive([]);
        let currentCanvas = null;
        let currentContext = null;
        let activeTool = ref(null); // 'text', 'image', 'draw', 'shape', 'editText', 'editImage'

        // --- Annotation Tool States ---
        const textAnnotation = reactive({
            fontFamily: 'Arial',
            fontSize: 16,
            bold: false,
            italic: false,
            underline: false,
            fontColor: '#000000',
            bgColor: '#ffffff',
            textAlign: 'left',
            opacity: 1,
            currentText: '',
            isAdding: false
        });

        const drawingMode = reactive({
            penColor: '#000000',
            penWidth: 3,
            isDrawing: false,
            lastX: 0,
            lastY: 0
        });

        const shapeAnnotation = reactive({
            type: 'Rectangle', // Line, Rectangle, Circle
            bgColor: '#ffffff',
            borderColor: '#000000',
            borderWidth: 2,
            borderRadius: 0, // For Rectangle
            opacity: 1,
            rotation: 0,
            isDrawing: false,
            startX: 0,
            startY: 0
        });
        
        let imageToDraw = null;
        let imageDragOffsetX = 0;
        let imageDragOffsetY = 0;
        let isDraggingImage = false;

        // --- PDF.js and PDF-Lib Instances ---
        let pdfJsDoc = null;
        let pdfLibDoc = null;

        // --- Canvas References ---
        const mainCanvasRef = ref(null);

        const activateEditor = async () => {
            console.log('activateEditor started. Current: pdfLoaded:', pdfLoaded.value, 'editorActive:', editorActive.value);
            editorActive.value = true;
            console.log('activateEditor set editorActive. New: pdfLoaded:', pdfLoaded.value, 'editorActive:', editorActive.value);
            await nextTick(); // Ensure editor section is rendered
            console.log('activateEditor after nextTick');
            await renderPage(currentPage.value); // Re-render page in editor context if needed
            // Potentially call fitWidth or other layout adjustments here if necessary
            console.log('activateEditor finished');
        };

        const startEditMode = () => {
            directEditMode.value = true;
            // Programmatically click the hidden file input
            document.getElementById('pdf-upload').click();
        };

        // --- Methods ---
        const handlePDFUpload = async (event) => {
            console.log('handlePDFUpload started');
            const file = event.target.files[0];
            if (file && file.type === 'application/pdf') {
                pdfFile.value = file;
                uploadError.value = null;
                console.log('Before loadPdf: pdfLoaded:', pdfLoaded.value, 'editorActive:', editorActive.value);
                await loadPdf();
                console.log('After loadPdf: pdfLoaded:', pdfLoaded.value, 'editorActive:', editorActive.value);

                // 自动进入编辑模式，无需点击编辑按钮
                if (pdfLoaded.value) {
                    console.log('Before activateEditor: pdfLoaded:', pdfLoaded.value, 'editorActive:', editorActive.value);
                    await activateEditor();
                    console.log('After activateEditor: pdfLoaded:', pdfLoaded.value, 'editorActive:', editorActive.value);
                }
            } else {
                pdfFile.value = null;
                pdfLoaded.value = false;
                uploadError.value = 'Please select a valid PDF file.';
                console.log('Invalid file in handlePDFUpload. Before resetEditorState: pdfLoaded:', pdfLoaded.value, 'editorActive:', editorActive.value);
                resetEditorState();
                console.log('Invalid file in handlePDFUpload. After resetEditorState: pdfLoaded:', pdfLoaded.value, 'editorActive:', editorActive.value);
            }
            console.log('handlePDFUpload finished');
        };

        const resetEditorState = () => {
            console.log('resetEditorState started. Current: pdfLoaded:', pdfLoaded.value, 'editorActive:', editorActive.value);
            pdfDoc.value = null;
            pdfLoaded.value = false;
            editorActive.value = false; // Reset editor active state
            numPages.value = 0;
            currentPage.value = 1;
            zoomLevel.value = 1.0;
            zoomLevelInput.value = 100;
            annotationHistory.splice(0, annotationHistory.length);
            pdfJsDoc = null;
            pdfLibDoc = null;
            activeTool.value = null;
            directEditMode.value = false;
            console.log('resetEditorState finished setting core states. New: pdfLoaded:', pdfLoaded.value, 'editorActive:', editorActive.value);
            // 清空文件输入框，以便用户可以重新选择相同的文件
            const fileInput = document.getElementById('pdf-upload');
            if (fileInput) fileInput.value = '';
        };

        const loadPdf = async () => {
            console.log('loadPdf started. Current: pdfLoaded:', pdfLoaded.value, 'editorActive:', editorActive.value);
            if (!pdfFile.value) {
                console.log('loadPdf: no pdfFile.value. Returning.');
                return;
            }
            const arrayBuffer = await pdfFile.value.arrayBuffer();
            
            // Load with PDF.js for rendering
            pdfJsDoc = await pdfjsLib.getDocument({ data: arrayBuffer }).promise;
            numPages.value = pdfJsDoc.numPages;
            
            // Load with PDF-Lib for editing
            pdfLibDoc = await PDFDocument.load(arrayBuffer);

            pdfLoaded.value = true;
            editorActive.value = false; // PDF is loaded, but editor is not yet active
            console.log('loadPdf set states. New: pdfLoaded:', pdfLoaded.value, 'editorActive:', editorActive.value);
            currentPage.value = 1;
            await renderPage(currentPage.value);
            await renderThumbnails();
            console.log('loadPdf finished');
        };

        const renderPage = async (pageNum) => {
            if (!pdfJsDoc || pageNum < 1 || pageNum > numPages.value) return;
            
            const page = await pdfJsDoc.getPage(pageNum);
            const viewport = page.getViewport({ scale: zoomLevel.value });
            
            const canvas = document.getElementById('pdf-canvas');
            if (!canvas) {
                console.error('Main canvas not found');
                return;
            }
            currentCanvas = canvas;
            const context = canvas.getContext('2d');
            currentContext = context;

            canvas.height = viewport.height;
            canvas.width = viewport.width;

            const renderContext = {
                canvasContext: context,
                viewport: viewport
            };
            await page.render(renderContext).promise;
            
            // Re-apply annotations for the current page
            await applyAnnotationsToPage(pageNum, context, viewport.scale);
        };

        const renderThumbnails = async () => {
            for (let i = 1; i <= numPages.value; i++) {
                await nextTick(); // Ensure canvas element is in DOM
                const page = await pdfJsDoc.getPage(i);
                const viewport = page.getViewport({ scale: 0.2 }); // Smaller scale for thumbnails
                const canvas = document.getElementById(`thumb-canvas-${i}`);
                if (canvas) {
                    const context = canvas.getContext('2d');
                    canvas.height = viewport.height;
                    canvas.width = viewport.width;
                    const renderContext = {
                        canvasContext: context,
                        viewport: viewport
                    };
                    page.render(renderContext);
                } else {
                    console.warn(`Thumbnail canvas for page ${i} not found.`);
                }
            }
            console.log('handlePDFUpload finished');
        };

        const switchPage = async (pageNum) => {
            if (pageNum >= 1 && pageNum <= numPages.value) {
                currentPage.value = pageNum;
                await renderPage(pageNum);
            }
            console.log('handlePDFUpload finished');
        };

        const prevPage = () => {
            if (currentPage.value > 1) {
                switchPage(currentPage.value - 1);
            }
            console.log('handlePDFUpload finished');
        };

        const nextPage = () => {
            if (currentPage.value < numPages.value) {
                switchPage(currentPage.value + 1);
            }
            console.log('handlePDFUpload finished');
        };

        const zoomIn = () => {
            zoomLevel.value = parseFloat((zoomLevel.value + 0.1).toFixed(1));
            zoomLevelInput.value = Math.round(zoomLevel.value * 100);
            renderPage(currentPage.value);
        };

        const zoomOut = () => {
            if (zoomLevel.value > 0.2) { // Minimum zoom to prevent issues
                zoomLevel.value = parseFloat((zoomLevel.value - 0.1).toFixed(1));
                zoomLevelInput.value = Math.round(zoomLevel.value * 100);
                renderPage(currentPage.value);
            }
            console.log('handlePDFUpload finished');
        };

        const setZoomLevelManually = () => {
            const newZoom = parseFloat(zoomLevelInput.value) / 100;
            if (newZoom > 0.1 && newZoom <= 5) { // Reasonable zoom limits
                zoomLevel.value = newZoom;
                renderPage(currentPage.value);
            } else {
                zoomLevelInput.value = Math.round(zoomLevel.value * 100); // Reset to current if invalid
            }
            console.log('handlePDFUpload finished');
        };

        const fitWidth = async () => {
            if (!pdfJsDoc || !currentCanvas) return;
            const page = await pdfJsDoc.getPage(currentPage.value);
            const viewport = page.getViewport({ scale: 1 }); // Get natural size
            const containerWidth = currentCanvas.parentElement.clientWidth - 20; // Subtract some padding
            zoomLevel.value = containerWidth / viewport.width;
            zoomLevelInput.value = Math.round(zoomLevel.value * 100);
            renderPage(currentPage.value);
        };
        
        const setDisplayMode = (event) => {
            displayMode.value = event.target.value;
            // This is a placeholder. Actual multi-page display (double, cover) is complex 
            // and would require significant changes to rendering logic, often involving 
            // multiple canvases or more advanced PDF.js features.
            // For now, it will just re-render the current single page.
            console.log("Display mode set to:", displayMode.value);
            renderPage(currentPage.value);
        };

        // --- Annotation Methods ---
        const activateTextMode = () => {
            deactivateAllTools();
            activeTool.value = 'text';
            textAnnotation.isAdding = true;
            currentCanvas.style.cursor = 'text';
            console.log("Text mode activated");
        };

        const addImageAnnotation = async (event) => {
            deactivateAllTools();
            activeTool.value = 'image';
            const file = event.target.files[0];
            if (file && file.type.startsWith('image/')) {
                const reader = new FileReader();
                reader.onload = (e) => {
                    const img = new Image();
                    img.onload = () => {
                        imageToDraw = img;
                        currentCanvas.style.cursor = 'copy';
                        // Prompt user to click on canvas to place image
                    };
                    img.src = e.target.result;
                };
                reader.readAsDataURL(file);
            }
            event.target.value = null; // Reset file input
        };

        const enableDrawingMode = () => {
            deactivateAllTools();
            activeTool.value = 'draw';
            drawingMode.isDrawing = false; // Will be set to true on mousedown
            currentCanvas.style.cursor = 'crosshair';
            console.log("Drawing mode enabled");
        };

        const activateShapeMode = () => {
            deactivateAllTools();
            activeTool.value = 'shape';
            shapeAnnotation.isDrawing = false; // Will be set to true on mousedown
            currentCanvas.style.cursor = 'crosshair';
            console.log("Shape mode activated with type:", shapeAnnotation.type);
        };

        const deactivateAllTools = () => {
            activeTool.value = null;
            textAnnotation.isAdding = false;
            drawingMode.isDrawing = false;
            shapeAnnotation.isDrawing = false;
            isDraggingImage = false;
            imageToDraw = null;
            currentCanvas.style.cursor = 'default';
        };

        const handleCanvasMouseDown = (event) => {
            if (!currentCanvas || !activeTool.value) return;
            const rect = currentCanvas.getBoundingClientRect();
            const x = event.clientX - rect.left;
            const y = event.clientY - rect.top;

            if (activeTool.value === 'draw') {
                drawingMode.isDrawing = true;
                drawingMode.lastX = x;
                drawingMode.lastY = y;
                currentContext.beginPath();
                currentContext.moveTo(x, y);
                currentContext.strokeStyle = drawingMode.penColor;
                currentContext.lineWidth = drawingMode.penWidth;
                currentContext.lineCap = 'round';
                currentContext.lineJoin = 'round';
            } else if (activeTool.value === 'shape') {
                shapeAnnotation.isDrawing = true;
                shapeAnnotation.startX = x;
                shapeAnnotation.startY = y;
            } else if (activeTool.value === 'image' && imageToDraw) {
                // Check if clicking on an existing image to drag
                let clickedOnExistingImage = false;
                for (let i = annotationHistory.length - 1; i >= 0; i--) {
                    const ann = annotationHistory[i];
                    if (ann.type === 'image' && ann.page === currentPage.value) {
                        const imgX = ann.x / zoomLevel.value;
                        const imgY = ann.y / zoomLevel.value;
                        const imgWidth = ann.width / zoomLevel.value;
                        const imgHeight = ann.height / zoomLevel.value;
                        if (x >= imgX && x <= imgX + imgWidth && y >= imgY && y <= imgY + imgHeight) {
                            isDraggingImage = true;
                            ann.isDragging = true; // Mark this specific annotation
                            imageDragOffsetX = x - imgX;
                            imageDragOffsetY = y - imgY;
                            clickedOnExistingImage = true;
                            currentCanvas.style.cursor = 'grabbing';
                            break;
                        }
                    }
                }
                if (!clickedOnExistingImage) {
                     // Place new image
                    const annotation = {
                        type: 'image',
                        page: currentPage.value,
                        img: imageToDraw, // Store the Image object itself for canvas drawing
                        x: x * zoomLevel.value, // Store in PDF coordinates
                        y: y * zoomLevel.value,
                        width: imageToDraw.width * zoomLevel.value, // Initial size, can be made resizable later
                        height: imageToDraw.height * zoomLevel.value,
                        rotation: 0,
                        opacity: 1,
                        description: `Image added to page ${currentPage.value}`
                    };
                    annotationHistory.push(annotation);
                    renderPage(currentPage.value); // Re-render to show new image
                    imageToDraw = null; // Reset for next image
                    currentCanvas.style.cursor = 'default';
                    activeTool.value = null; // Deactivate after placing
                }
            }
            console.log('handlePDFUpload finished');
        };

        const handleCanvasMouseMove = (event) => {
            if (!currentCanvas || !activeTool.value) return;
            const rect = currentCanvas.getBoundingClientRect();
            const x = event.clientX - rect.left;
            const y = event.clientY - rect.top;

            if (activeTool.value === 'draw' && drawingMode.isDrawing) {
                currentContext.lineTo(x, y);
                currentContext.stroke();
                drawingMode.lastX = x;
                drawingMode.lastY = y;
            } else if (activeTool.value === 'shape' && shapeAnnotation.isDrawing) {
                renderPage(currentPage.value); // Redraw page to clear previous temp shape
                currentContext.globalAlpha = shapeAnnotation.opacity;
                currentContext.fillStyle = shapeAnnotation.bgColor;
                currentContext.strokeStyle = shapeAnnotation.borderColor;
                currentContext.lineWidth = shapeAnnotation.borderWidth;
                
                const width = x - shapeAnnotation.startX;
                const height = y - shapeAnnotation.startY;

                currentContext.save();
                // Translate and rotate for shape rotation (more complex for live preview)
                // For simplicity, rotation is applied when finalizing the shape here.
                // For live rotation preview, you'd apply transform before drawing each frame.

                if (shapeAnnotation.type === 'Rectangle') {
                    // Simple rect for now, borderRadius needs more complex path drawing
                    currentContext.beginPath();
                    if (shapeAnnotation.borderRadius > 0) {
                        // Custom rounded rect drawing logic needed here for live preview
                        // For simplicity, pdf-lib will handle rounded rects on export.
                        // Drawing a simple rect for preview.
                        currentContext.rect(shapeAnnotation.startX, shapeAnnotation.startY, width, height);
                    } else {
                        currentContext.rect(shapeAnnotation.startX, shapeAnnotation.startY, width, height);
                    }
                    if (shapeAnnotation.bgColor !== 'transparent' && shapeAnnotation.bgColor !== '#ffffff') currentContext.fill();
                    if (shapeAnnotation.borderWidth > 0) currentContext.stroke();
                } else if (shapeAnnotation.type === 'Circle') {
                    currentContext.beginPath();
                    const radiusX = Math.abs(width / 2);
                    const radiusY = Math.abs(height / 2);
                    const centerX = shapeAnnotation.startX + width / 2;
                    const centerY = shapeAnnotation.startY + height / 2;
                    currentContext.ellipse(centerX, centerY, radiusX, radiusY, 0, 0, 2 * Math.PI);
                    if (shapeAnnotation.bgColor !== 'transparent' && shapeAnnotation.bgColor !== '#ffffff') currentContext.fill();
                    if (shapeAnnotation.borderWidth > 0) currentContext.stroke();
                } else if (shapeAnnotation.type === 'Line') {
                    currentContext.beginPath();
                    currentContext.moveTo(shapeAnnotation.startX, shapeAnnotation.startY);
                    currentContext.lineTo(x, y);
                    if (shapeAnnotation.borderWidth > 0) currentContext.stroke();
                }
                currentContext.restore();
                currentContext.globalAlpha = 1.0; // Reset global alpha
            } else if (activeTool.value === 'image' && isDraggingImage) {
                const draggedAnnotation = annotationHistory.find(ann => ann.isDragging);
                if (draggedAnnotation) {
                    draggedAnnotation.x = (x - imageDragOffsetX) * zoomLevel.value;
                    draggedAnnotation.y = (y - imageDragOffsetY) * zoomLevel.value;
                    renderPage(currentPage.value); // Re-render to show dragged image
                }
            }
            console.log('handlePDFUpload finished');
        };

        const handleCanvasMouseUp = (event) => {
            if (!currentCanvas || !activeTool.value) return;
            const rect = currentCanvas.getBoundingClientRect();
            const x = event.clientX - rect.left;
            const y = event.clientY - rect.top;

            if (activeTool.value === 'draw' && drawingMode.isDrawing) {
                drawingMode.isDrawing = false;
                currentContext.closePath();
                // Store drawn path as an annotation
                const imageData = currentCanvas.toDataURL(); // Simplistic: save entire canvas state for freehand
                                                        // Better: store path commands
                annotationHistory.push({
                    type: 'draw',
                    page: currentPage.value,
                    imageData: imageData, // This will be drawn over the PDF page content
                    // For PDF-Lib, you'd convert these to vector paths if possible
                    // For simplicity here, we'll re-draw this image data on the PDF-Lib page
                    description: `Drawing on page ${currentPage.value}`,
                    // Store path data for pdf-lib
                    path: currentContext.currentPath, // This is not standard, need to capture path segments
                    color: drawingMode.penColor,
                    width: drawingMode.penWidth
                });
                activeTool.value = null;
                currentCanvas.style.cursor = 'default';
            } else if (activeTool.value === 'shape' && shapeAnnotation.isDrawing) {
                shapeAnnotation.isDrawing = false;
                const width = (x - shapeAnnotation.startX);
                const height = (y - shapeAnnotation.startY);

                const newShape = {
                    type: 'shape',
                    shapeType: shapeAnnotation.type,
                    page: currentPage.value,
                    x: shapeAnnotation.startX * zoomLevel.value,
                    y: shapeAnnotation.startY * zoomLevel.value,
                    width: width * zoomLevel.value,
                    height: height * zoomLevel.value,
                    bgColor: shapeAnnotation.bgColor,
                    borderColor: shapeAnnotation.borderColor,
                    borderWidth: shapeAnnotation.borderWidth,
                    borderRadius: shapeAnnotation.type === 'Rectangle' ? shapeAnnotation.borderRadius : 0,
                    opacity: shapeAnnotation.opacity,
                    rotation: shapeAnnotation.rotation, // Degrees
                    description: `${shapeAnnotation.type} added to page ${currentPage.value}`
                };
                annotationHistory.push(newShape);
                renderPage(currentPage.value); // Final render with the shape from history
                activeTool.value = null;
                currentCanvas.style.cursor = 'default';
            } else if (activeTool.value === 'text' && textAnnotation.isAdding) {
                const text = prompt("Enter text:", textAnnotation.currentText);
                if (text) {
                    annotationHistory.push({
                        type: 'text',
                        page: currentPage.value,
                        text: text,
                        x: x * zoomLevel.value,
                        y: y * zoomLevel.value,
                        fontFamily: textAnnotation.fontFamily,
                        fontSize: textAnnotation.fontSize,
                        bold: textAnnotation.bold,
                        italic: textAnnotation.italic,
                        underline: textAnnotation.underline,
                        fontColor: textAnnotation.fontColor,
                        bgColor: textAnnotation.bgColor,
                        textAlign: textAnnotation.textAlign,
                        opacity: textAnnotation.opacity,
                        description: `Text "${text.substring(0,20)}..." on page ${currentPage.value}`
                    });
                    renderPage(currentPage.value);
                }
                textAnnotation.isAdding = false;
                activeTool.value = null;
                currentCanvas.style.cursor = 'default';
            } else if (activeTool.value === 'image' && isDraggingImage) {
                const draggedAnnotation = annotationHistory.find(ann => ann.isDragging);
                if (draggedAnnotation) {
                    delete draggedAnnotation.isDragging; // Clear dragging flag
                }
                isDraggingImage = false;
                currentCanvas.style.cursor = 'default'; // Or 'copy' if imageToDraw is still set
                // activeTool.value = null; // Keep image tool active for more placements or drags unless explicitly changed
            }
            console.log('handlePDFUpload finished');
        };
        
        const handleCanvasMouseLeave = (event) => {
            // If drawing and mouse leaves canvas, finalize the drawing/shape
            if (activeTool.value === 'draw' && drawingMode.isDrawing) {
                handleCanvasMouseUp(event); 
            } else if (activeTool.value === 'shape' && shapeAnnotation.isDrawing) {
                handleCanvasMouseUp(event);
            } else if (activeTool.value === 'image' && isDraggingImage) {
                handleCanvasMouseUp(event);
            }
            console.log('handlePDFUpload finished');
        };

        const applyAnnotationsToPage = async (pageNum, context, scale) => {
            for (const ann of annotationHistory) {
                if (ann.page !== pageNum) continue;

                context.globalAlpha = ann.opacity || 1;
                const x = ann.x / scale;
                const y = ann.y / scale;
                
                if (ann.type === 'text') {
                    context.font = `${ann.bold ? 'bold ' : ''}${ann.italic ? 'italic ' : ''}${ann.fontSize / scale}px ${ann.fontFamily}`;
                    context.fillStyle = ann.fontColor;
                    context.textAlign = ann.textAlign;
                    // Background for text is tricky on canvas, pdf-lib handles it better.
                    // For canvas preview, we might draw a rect behind.
                    if (ann.bgColor && ann.bgColor !== '#ffffff' && ann.bgColor !== 'transparent') {
                        const textMetrics = context.measureText(ann.text);
                        // Approximate background height. More accurate calculation needed.
                        const textHeight = ann.fontSize / scale * 1.2;
                        context.fillStyle = ann.bgColor;
                        let bgX = x;
                        if(ann.textAlign === 'center') bgX = x - textMetrics.width / 2;
                        else if(ann.textAlign === 'right') bgX = x - textMetrics.width;
                        context.fillRect(bgX, y - textHeight * 0.8, textMetrics.width, textHeight);
                        context.fillStyle = ann.fontColor; // Reset for text
                    }
                    context.fillText(ann.text, x, y);
                } else if (ann.type === 'image' && ann.img) {
                    const imgWidth = ann.width / scale;
                    const imgHeight = ann.height / scale;
                    // TODO: Add rotation for images on canvas if ann.rotation is set
                    context.drawImage(ann.img, x, y, imgWidth, imgHeight);
                } else if (ann.type === 'draw' && ann.imageData) {
                    // This is a simplified way for freehand. It redraws the saved canvas state.
                    // This will draw ON TOP of the PDF page content.
                    // For true vector drawing, you'd store path commands and replay them.
                    const drawingImage = new Image();
                    drawingImage.onload = () => {
                        context.drawImage(drawingImage, 0, 0);
                    };
                    drawingImage.src = ann.imageData; 
                } else if (ann.type === 'shape') {
                    const shapeWidth = ann.width / scale;
                    const shapeHeight = ann.height / scale;
                    context.fillStyle = ann.bgColor;
                    context.strokeStyle = ann.borderColor;
                    context.lineWidth = ann.borderWidth / scale;

                    context.save();
                    // Apply rotation - translate to shape center, rotate, translate back
                    const centerX = x + shapeWidth / 2;
                    const centerY = y + shapeHeight / 2;
                    context.translate(centerX, centerY);
                    context.rotate(ann.rotation * Math.PI / 180);
                    context.translate(-centerX, -centerY);

                    if (ann.shapeType === 'Rectangle') {
                        context.beginPath();
                        if (ann.borderRadius > 0) {
                            const r = ann.borderRadius / scale;
                            context.moveTo(x + r, y);
                            context.lineTo(x + shapeWidth - r, y);
                            context.quadraticCurveTo(x + shapeWidth, y, x + shapeWidth, y + r);
                            context.lineTo(x + shapeWidth, y + shapeHeight - r);
                            context.quadraticCurveTo(x + shapeWidth, y + shapeHeight, x + shapeWidth - r, y + shapeHeight);
                            context.lineTo(x + r, y + shapeHeight);
                            context.quadraticCurveTo(x, y + shapeHeight, x, y + shapeHeight - r);
                            context.lineTo(x, y + r);
                            context.quadraticCurveTo(x, y, x + r, y);
                            context.closePath();
                        } else {
                            context.rect(x, y, shapeWidth, shapeHeight);
                        }
                        if (ann.bgColor && ann.bgColor !== 'transparent' && ann.bgColor !== '#ffffff') context.fill();
                        if (ann.borderWidth > 0) context.stroke();
                    } else if (ann.shapeType === 'Circle') {
                        context.beginPath();
                        context.ellipse(x + shapeWidth / 2, y + shapeHeight / 2, Math.abs(shapeWidth / 2), Math.abs(shapeHeight / 2), 0, 0, 2 * Math.PI);
                        if (ann.bgColor && ann.bgColor !== 'transparent' && ann.bgColor !== '#ffffff') context.fill();
                        if (ann.borderWidth > 0) context.stroke();
                    } else if (ann.shapeType === 'Line') {
                        context.beginPath();
                        context.moveTo(x, y);
                        context.lineTo(x + shapeWidth, y + shapeHeight); // Line uses width/height as end point relative to start
                        if (ann.borderWidth > 0) context.stroke();
                    }
                    context.restore();
                }
                context.globalAlpha = 1.0; // Reset global alpha
            }
            console.log('handlePDFUpload finished');
        };

        // --- PDF Editing (Placeholder) ---
        const editText = () => {
            deactivateAllTools();
            activeTool.value = 'editText';
            alert('Editing existing PDF text is complex and not fully implemented in this demo. Annotations allow adding new text.');
            // True PDF text editing requires identifying text blocks, fonts, etc.
            // PDF-Lib can modify existing text if you know its exact properties and location.
        };

        const editImage = () => {
            deactivateAllTools();
            activeTool.value = 'editImage';
            alert('Editing existing PDF images is complex (e.g., replacing). Annotations allow adding new images.');
            // PDF-Lib can replace images if you identify them.
        };

        // --- History Management ---
        const editHistoryItem = (index) => {
            const item = annotationHistory[index];
            // For simplicity, just log. Actual editing would repopulate controls and allow re-adding.
            console.log("Editing history item:", item);
            alert(`Editing history item: ${item.description}. Feature to re-edit parameters is advanced.`);
            // To implement fully: remove item, set activeTool and its state, let user re-draw/re-place.
        };

        const deleteHistoryItem = (index) => {
            annotationHistory.splice(index, 1);
            renderPage(currentPage.value);
        };

        // --- Export PDF ---
        const exportPDF = async () => {
            if (!pdfLibDoc) return;

            // Create a new PDFDocument or use the loaded one for modifications
            // For simplicity, we'll add annotations to the existing pdfLibDoc
            const pages = pdfLibDoc.getPages();

            for (const ann of annotationHistory) {
                if (ann.page < 1 || ann.page > pages.length) continue;
                const page = pages[ann.page - 1];
                const { width: pageWidth, height: pageHeight } = page.getSize();

                // PDF-Lib coordinates are from bottom-left
                const pdfLibX = ann.x;
                const pdfLibY = pageHeight - ann.y - (ann.height || (ann.fontSize || 0)); // Adjust Y for bottom-left origin

                if (ann.type === 'text') {
                    let font = await pdfLibDoc.embedFont(StandardFonts.Helvetica);
                    if (ann.fontFamily.toLowerCase().includes('times')) font = await pdfLibDoc.embedFont(StandardFonts.TimesRoman);
                    if (ann.fontFamily.toLowerCase().includes('courier')) font = await pdfLibDoc.embedFont(StandardFonts.Courier);
                    if (ann.bold && ann.italic) {
                        if (ann.fontFamily.toLowerCase().includes('times')) font = await pdfLibDoc.embedFont(StandardFonts.TimesRomanBoldItalic);
                        else if (ann.fontFamily.toLowerCase().includes('courier')) font = await pdfLibDoc.embedFont(StandardFonts.CourierBoldOblique);
                        else font = await pdfLibDoc.embedFont(StandardFonts.HelveticaBoldOblique);
                    } else if (ann.bold) {
                         if (ann.fontFamily.toLowerCase().includes('times')) font = await pdfLibDoc.embedFont(StandardFonts.TimesRomanBold);
                        else if (ann.fontFamily.toLowerCase().includes('courier')) font = await pdfLibDoc.embedFont(StandardFonts.CourierBold);
                        else font = await pdfLibDoc.embedFont(StandardFonts.HelveticaBold);
                    } else if (ann.italic) {
                        if (ann.fontFamily.toLowerCase().includes('times')) font = await pdfLibDoc.embedFont(StandardFonts.TimesRomanItalic);
                        else if (ann.fontFamily.toLowerCase().includes('courier')) font = await pdfLibDoc.embedFont(StandardFonts.CourierOblique);
                        else font = await pdfLibDoc.embedFont(StandardFonts.HelveticaOblique);
                    }

                    const textColor = ann.fontColor.startsWith('#') ? rgb(...hexToRgb(ann.fontColor)) : rgb(0,0,0);
                    let textY = pageHeight - ann.y - ann.fontSize; // Adjust for text baseline
                    
                    page.drawText(ann.text, {
                        x: ann.x,
                        y: textY, 
                        font: font,
                        size: ann.fontSize,
                        color: textColor,
                        opacity: ann.opacity,
                        // lineHeight, underline, etc. might need custom drawing or more advanced pdf-lib features
                    });
                } else if (ann.type === 'image' && ann.img && ann.img.src) {
                    let imageBytes;
                    if (ann.img.src.startsWith('data:image/png')) {
                        imageBytes = await fetch(ann.img.src).then(res => res.arrayBuffer());
                        const pdfImage = await pdfLibDoc.embedPng(imageBytes);
                        page.drawImage(pdfImage, {
                            x: ann.x,
                            y: pageHeight - ann.y - ann.height, // Adjust Y
                            width: ann.width,
                            height: ann.height,
                            opacity: ann.opacity,
                            rotate: PDFLib.degrees(ann.rotation || 0)
                        });
                    } else if (ann.img.src.startsWith('data:image/jpeg') || ann.img.src.startsWith('data:image/jpg')) {
                        imageBytes = await fetch(ann.img.src).then(res => res.arrayBuffer());
                        const pdfImage = await pdfLibDoc.embedJpg(imageBytes);
                         page.drawImage(pdfImage, {
                            x: ann.x,
                            y: pageHeight - ann.y - ann.height, // Adjust Y
                            width: ann.width,
                            height: ann.height,
                            opacity: ann.opacity,
                            rotate: PDFLib.degrees(ann.rotation || 0)
                        });
                    }
                } else if (ann.type === 'shape') {
                    const shapeX = ann.x;
                    const shapeY = pageHeight - ann.y - ann.height; // Y for bottom-left origin, height for top of shape
                    const shapeWidth = ann.width;
                    const shapeHeight = ann.height;
                    const options = {
                        x: shapeX,
                        y: shapeY,
                        width: shapeWidth,
                        height: shapeHeight,
                        color: ann.bgColor && ann.bgColor !== 'transparent' && ann.bgColor !== '#ffffff' ? rgb(...hexToRgb(ann.bgColor)) : undefined,
                        borderColor: ann.borderColor ? rgb(...hexToRgb(ann.borderColor)) : undefined,
                        borderWidth: ann.borderWidth,
                        opacity: ann.opacity,
                        rotate: PDFLib.degrees(ann.rotation || 0),
                        borderRadius: ann.shapeType === 'Rectangle' ? ann.borderRadius : undefined
                    };

                    if (ann.shapeType === 'Rectangle') {
                        page.drawRectangle(options);
                    } else if (ann.shapeType === 'Circle') {
                        // PDF-Lib draws ellipse from center
                        page.drawEllipse({
                            x: shapeX + shapeWidth / 2,
                            y: shapeY + shapeHeight / 2,
                            xScale: Math.abs(shapeWidth / 2),
                            yScale: Math.abs(shapeHeight / 2),
                            color: options.color,
                            borderColor: options.borderColor,
                            borderWidth: options.borderWidth,
                            opacity: options.opacity,
                            rotate: options.rotate
                        });
                    } else if (ann.shapeType === 'Line') {
                        page.drawLine({
                            start: { x: shapeX, y: pageHeight - ann.y }, // Line start Y is different
                            end: { x: shapeX + shapeWidth, y: pageHeight - (ann.y + ann.height) }, // Line end Y
                            thickness: ann.borderWidth,
                            color: ann.borderColor ? rgb(...hexToRgb(ann.borderColor)) : rgb(0,0,0),
                            opacity: ann.opacity,
                            // Rotation for lines is complex, typically applied to the page or a form XObject
                        });
                    }
                } else if (ann.type === 'draw' && ann.path) { // Simplified draw export
                    // This is a very basic export for freehand. Ideally, convert canvas path to PDF path commands.
                    // For now, we're not fully implementing this due to complexity of path conversion.
                    // A workaround could be to rasterize the drawing onto an image and embed that.
                    console.warn("Exporting freehand drawing is simplified and may not be vector perfect.");
                    // Example: draw a simple line if path data was structured for it
                    // page.drawLine({ start: {x:..., y:...}, end: {x:..., y:...}, color: ..., thickness: ... });
                }
            }

            const pdfBytes = await pdfLibDoc.save();
            const blob = new Blob([pdfBytes], { type: 'application/pdf' });
            const link = document.createElement('a');
            link.href = URL.createObjectURL(blob);
            link.download = pdfFile.value ? `edited_${pdfFile.value.name}` : 'edited_document.pdf';
            link.click();
            URL.revokeObjectURL(link.href);
        };

        function hexToRgb(hex) {
            const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
            return result ? [
                parseInt(result[1], 16) / 255,
                parseInt(result[2], 16) / 255,
                parseInt(result[3], 16) / 255
            ] : [0,0,0];
        }

        onMounted(() => {
            // Setup canvas listeners after component is mounted and canvas element exists
            nextTick(() => {
                const canvasEl = document.getElementById('pdf-canvas');
                if (canvasEl) {
                    canvasEl.addEventListener('mousedown', handleCanvasMouseDown);
                    canvasEl.addEventListener('mousemove', handleCanvasMouseMove);
                    canvasEl.addEventListener('mouseup', handleCanvasMouseUp);
                    canvasEl.addEventListener('mouseleave', handleCanvasMouseLeave);
                } else {
                    // This might happen if v-if="pdfLoaded" is false initially.
                    // We might need a watcher on pdfLoaded to attach listeners when canvas becomes available.
                    console.warn("Main PDF canvas not found on mount. Listeners will be attached when PDF loads.");
                }
            });
        });
        
        // Watch for pdfLoaded to attach listeners if canvas wasn't ready on initial mount
        watch(pdfLoaded, (newVal) => {
            if (newVal) {
                nextTick(() => {
                    const canvasEl = document.getElementById('pdf-canvas');
                    if (canvasEl && !canvasEl.hasAttribute('data-listeners-attached')) {
                        canvasEl.addEventListener('mousedown', handleCanvasMouseDown);
                        canvasEl.addEventListener('mousemove', handleCanvasMouseMove);
                        canvasEl.addEventListener('mouseup', handleCanvasMouseUp);
                        canvasEl.addEventListener('mouseleave', handleCanvasMouseLeave);
                        canvasEl.setAttribute('data-listeners-attached', 'true');
                    }
                });
            }
        });


        return {
            pdfLoaded,
            numPages,
            currentPage,
            zoomLevel,
            zoomLevelInput,
            displayMode,
            uploadError,
            annotationHistory,
            textAnnotation,
            drawingMode,
            shapeAnnotation,
            editorActive, // Expose new state
            activateEditor, // Expose new method
            activeTool,

            handlePDFUpload,
            switchPage,
            prevPage,
            nextPage,
            zoomIn,
            zoomOut,
            setZoomLevelManually,
            fitWidth,
            setDisplayMode,
            
            activateTextMode,
            addImageAnnotation,
            enableDrawingMode,
            activateShapeMode,
            deactivateAllTools,

            editText,
            editImage,
            editHistoryItem,
            deleteHistoryItem,
            exportPDF,
            startEditMode, // Expose startEditMode to the template
            resetEditorState, // 暴露重置函数给模板
        };
    }
}).mount('#pdf-editor-app');